Estruturas de dados

Row

Vetor

Declaração de vetores.

vet_int <- c(5L, 23L, 58L, 47L)
vet_bool <- c(F, T, T, T)
vet_num <- c(109.1, 165.3, 147.7, 182.5)
vet_char<- c("Tim", "Bill", "Rosa", "Alex")
Também é possível declacar um vetor de números imaginários
vet_img <- c(1.50i, 2.50i, 3.50i, 4.50i)
Verificando as classes dos vetores.
Nos vetores, todos os elementos são do mesmo tipo de dado.
class(vet_int)
[1] "integer"
class(vet_bool)
[1] "logical"
class(vet_num)
[1] "numeric"
class(vet_char)
[1] "character"
class(vet_img)
[1] "complex"

Podemos verificar se os elementos do vetor vet_int são realmente inteiros.

is.integer(vet_int)
[1] TRUE
Operações com vetores
vet_int * 2 #multiplica cada elemento por 2
[1]  10  46 116  94
vet_num / 3.4
[1] 32.08824 48.61765 43.44118 53.67647
vet_int + 7
[1] 12 30 65 54
vet_int + c(3, 4, 1)
[1]  8 27 59 50

Como os dois vetores não possuiam o mesmo tamanho, o vetor menor foi repetido até completar o vetor maior. Isso é chamado Reciclagem.

Vetores aceitam apenas um tipo de dado, na seguinte ordem de precedência: character > complex > numeric > integer > logical
x <- c(5L, 6.4)
class(x) # o vetor ficou como numérico
[1] "numeric"
x <- c(5L, 6.4, "abc")
class(x) # o vetor passou a ser character
[1] "character"
Podemos forçar um vetor a ser de um tipo específico
x <- -3:2
x
[1] -3 -2 -1  0  1  2
class(x)
[1] "integer"
y <-as.numeric(x)
y
[1] -3 -2 -1  0  1  2
class(y)
[1] "numeric"
y <- as.logical(x)
y # apenos 0 é false
[1]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE
class(y)
[1] "logical"
y <- as.character(x)
y
[1] "-3" "-2" "-1" "0"  "1"  "2" 
class(y)
[1] "character"

Matriz

Declaração de uma matriz 4*3

matriz <- matrix(c(1:12), nrow = 4, ncol = 3, byrow = T)
matriz
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
[4,]   10   11   12
Verificando a classe e as dimensões da matriz:
paste("A classe é: ", class(matriz)[1] )
[1] "A classe é:  matrix"
dimensoes <- dim(matriz)
paste("As dimensões da matriz são: ", dimensoes[1], "x", dimensoes[2])
[1] "As dimensões da matriz são:  4 x 3"

Podemos criar uma matriz utilizando alguns dos vetores criados até agora.

matriz2 <- matrix(c(vet_char, vet_int, vet_num), nrow = 4, byrow = F)
matriz2
     [,1]   [,2] [,3]   
[1,] "Tim"  "5"  "109.1"
[2,] "Bill" "23" "165.3"
[3,] "Rosa" "58" "147.7"
[4,] "Alex" "47" "182.5"

Como matrizes aceitam apenas um tipo de dado, acabamos transformando todos os elementos no tipo character.
Podemos utilizar a primeira coluna como nome das linhas, dessa forma, as demais variáveis vão assumir o tipo numeric, que é mais abrangente do que o tipo integer

matriz2 <- matrix(c(vet_int, vet_num), nrow = 4, byrow = F)
rownames(matriz2) <- vet_char
matriz2
     [,1]  [,2]
Tim     5 109.1
Bill   23 165.3
Rosa   58 147.7
Alex   47 182.5
Agora, daremos nomes às colunas.
colnames(matriz2) <- c("idade", "altura(cm)")
matriz2
     idade altura(cm)
Tim      5      109.1
Bill    23      165.3
Rosa    58      147.7
Alex    47      182.5
Subsets
matriz2[1,] #seleciona a primeira linha
     idade altura(cm) 
       5.0      109.1 
matriz2[,2] #seleciona a segunda coluna
  Tim  Bill  Rosa  Alex 
109.1 165.3 147.7 182.5 
matriz2[2,2] #seleciona o elemento da segunda linha e segunda coluna
[1] 165.3
Matriz transposta
t(matriz2)
             Tim  Bill  Rosa  Alex
idade        5.0  23.0  58.0  47.0
altura(cm) 109.1 165.3 147.7 182.5
Multiplicação de matrizes
m1 <- matrix(1:8, nrow = 4, ncol = 2)
m2 <- matrix(10:17, nrow = 2, ncol = 4)
m1 %*% m2 
     [,1] [,2] [,3] [,4]
[1,]   65   77   89  101
[2,]   86  102  118  134
[3,]  107  127  147  167
[4,]  128  152  176  200
Matriz inversa e diagonal principal
m1 <- matrix(1:4, nrow = 2, ncol = 2)
m1
     [,1] [,2]
[1,]    1    3
[2,]    2    4
solve(m1) # matriz inversa, a matriz tem que ser quadrada
     [,1] [,2]
[1,]   -2  1.5
[2,]    1 -0.5
diag(m1) #diagonal principal
[1] 1 4

Dataframe

Dataframes são similares à matrizes, mas possuem funções específicas como busca e indexação. Permitem que cada coluna seja de um tipo diferente.

df <- data.frame(vet_int, vet_num, row.names = vet_char)
colnames(df) <- c("idade", "altura(cm)")
df
     idade altura(cm)
Tim      5      109.1
Bill    23      165.3
Rosa    58      147.7
Alex    47      182.5
Verificando os tipos das colunas:
str(df)
'data.frame':   4 obs. of  2 variables:
 $ idade     : int  5 23 58 47
 $ altura(cm): num  109 165 148 182
Podemos adicionar mais uma coluna:
df <- cbind(df, maioridade = df$idade > 18)
df
     idade altura(cm) maioridade
Tim      5      109.1      FALSE
Bill    23      165.3       TRUE
Rosa    58      147.7       TRUE
Alex    47      182.5       TRUE
E uma nova linha
df <- rbind(df, "Pam" = list(32L, 172, TRUE))
df
     idade altura(cm) maioridade
Tim      5      109.1      FALSE
Bill    23      165.3       TRUE
Rosa    58      147.7       TRUE
Alex    47      182.5       TRUE
Pam     32      172.0       TRUE
As 2 primeiras linhas desse dataset:
head(df, n=2)
     idade altura(cm) maioridade
Tim      5      109.1      FALSE
Bill    23      165.3       TRUE
As duas últimas linhas:
tail(df, n=2)
     idade altura(cm) maioridade
Alex    47      182.5       TRUE
Pam     32      172.0       TRUE

Lista

Listas permitem que cada elemento seja de um tipo de dado.
Um conjunto de listas do mesmo tamanho forma um dataset.

lista1 <- list("lista", 99L, 0.983, F)
lista1
[[1]]
[1] "lista"

[[2]]
[1] 99

[[3]]
[1] 0.983

[[4]]
[1] FALSE
str(lista1)
List of 4
 $ : chr "lista"
 $ : int 99
 $ : num 0.983
 $ : logi FALSE
Podemos criar uma lista com todos os vetores criados até agora
lista2 <- list("boolean"=vet_bool, "char"=vet_char, vet_img, vet_int, vet_num)
lista2
$boolean
[1] FALSE  TRUE  TRUE  TRUE

$char
[1] "Tim"  "Bill" "Rosa" "Alex"

[[3]]
[1] 0+1.5i 0+2.5i 0+3.5i 0+4.5i

[[4]]
[1]  5 23 58 47

[[5]]
[1] 109.1 165.3 147.7 182.5
str(lista2)
List of 5
 $ boolean: logi [1:4] FALSE TRUE TRUE TRUE
 $ char   : chr [1:4] "Tim" "Bill" "Rosa" "Alex"
 $        : cplx [1:4] 0+1.5i 0+2.5i 0+3.5i ...
 $        : int [1:4] 5 23 58 47
 $        : num [1:4] 109 165 148 182
Subsets:
lista2[1] #retorna uma sub-lista
$boolean
[1] FALSE  TRUE  TRUE  TRUE
lista2[[1]] #retorna o primeiro elemento da lista
[1] FALSE  TRUE  TRUE  TRUE
lista2$boolean #filtra pelo nome do elemento
[1] FALSE  TRUE  TRUE  TRUE

Fator

Fatores servem para expressar variáveis categóricas.

temperatura <- c("frio", "calor", "ameno", "calor", "ameno", "frio")
temperatura.factor <- factor(temperatura, ordered = T, levels=c("frio", "ameno", "calor"))
temperatura.factor
[1] frio  calor ameno calor ameno frio 
Levels: frio < ameno < calor
unclass(temperatura.factor)
[1] 1 3 2 3 2 1
attr(,"levels")
[1] "frio"  "ameno" "calor"
levels(temperatura.factor)
[1] "frio"  "ameno" "calor"

Datas

Data e hora
dia_texto <- "01/08/2020 T 16:35:23"
dia_date <- as.Date(dia_texto,format="%d/%m/%Y T %H:%M:%S",tz="America/Sao_Paulo")
dia_date
[1] "2020-08-01"
unclass(dia_date) #valor representa (01/08/2020) - (01/01/1970) em dias
[1] 18475

POSIXct - número de segundos a partir de 01/01/1970

dia.time1 <- as.POSIXct(dia_texto,format="%d/%m/%Y T %H:%M:%S",tz="America/Sao_Paulo") 
dia.time1
[1] "2020-08-01 16:35:23 -03"
unclass(dia.time1) #valor representa (01/08/2020) - (01/01/1970) em segundos
[1] 1596310523
attr(,"tzone")
[1] "America/Sao_Paulo"
POSIXlt - Lista com elementos ano, mês, dia, hora, entre outros
dia.time2 <- as.POSIXlt(dia_texto,format="%d/%m/%Y T %H:%M:%S",tz="America/Sao_Paulo")
dia.time2
[1] "2020-08-01 16:35:23 -03"
unclass(dia.time2)
$sec
[1] 23

$min
[1] 35

$hour
[1] 16

$mday
[1] 1

$mon
[1] 7

$year
[1] 120

$wday
[1] 6

$yday
[1] 213

$isdst
[1] 0

$zone
[1] "-03"

$gmtoff
[1] NA

attr(,"tzone")
[1] "America/Sao_Paulo"
Como dia.time tem o elemeno chamado year, podemos fazer:
dia.time2$year
[1] 120
O pacote lubridate facilita a manipulação de datas
library(lubridate)

ymd("20200801") #Cria uma data sabendo que está na ordem ano, mês, dia
[1] "2020-08-01"
dmy("01.08.2020") #Cria uma data sabendo que está na ordem dia, mês, ano
[1] "2020-08-01"
nascimento <- ymd_hms(19990704130752)
nascimento
[1] "1999-07-04 13:07:52 UTC"
year(nascimento) #ano da data
[1] 1999
second(nascimento) #segundos da data
[1] 52
wday(nascimento) #dia da semana
[1] 1
wday(nascimento, label = T)
[1] dom
Levels: dom < seg < ter < qua < qui < sex < sáb
month(nascimento, label = T)
[1] jul
12 Levels: jan < fev < mar < abr < mai < jun < jul < ago < set < ... < dez
Essas funções também podem ser usadas para atribuir componentes a datas:
dia1 <- ymd(20180417, tz = "America/Sao_Paulo")
hour(dia1) <- 13
second(dia1) <- 24
dia1
[1] "2018-04-17 13:00:24 -03"
Fuso horário
tz(dia1)
[1] "America/Sao_Paulo"
with_tz(dia1, tzone = "US/Alaska") #data/hora equivalente em outro timezone
[1] "2018-04-17 08:00:24 AKDT"
dia1 <- force_tz(dia1, tz = "Asia/Singapore") #altera o timezone
tz(dia1)
[1] "Asia/Singapore"
Operações com datas
data_inicio <- dmy("03/03/1986")
data_fim <- dmy("18/06/2017")

intervalo1 <- interval(data_inicio, data_fim)
intervalo1
[1] 1986-03-03 UTC--2017-06-18 UTC
class(intervalo1)
[1] "Interval"
attr(,"package")
[1] "lubridate"
Outras formas de obter o intervalo
data_fim - data_inicio
Time difference of 11430 days
difftime(data_fim, data_inicio)
Time difference of 11430 days
difftime(data_fim, data_inicio, unit="secs")
Time difference of 987552000 secs
difftime(data_fim, data_inicio, unit="days")
Time difference of 11430 days
É possível verificar se dois intervalos de tempo se sobrepõem
intervalo2 <- dmy("04-03-2000") %--% dmy("20/03/2018")  # Operador %--% para intervalo
int_overlaps(intervalo1, intervalo2)
[1] TRUE
Aritmética com datas
days(1) #cria um dia
[1] "1d 0H 0M 0S"
ddays(1) # cria uma duração de um dia em segundos
[1] "86400s (~1 days)"
data_inicio + ddays(1)
[1] "1986-03-04"
data_inicio + years(2)
[1] "1988-03-03"
#Criar datas recorrentes
data_inicio + months(1:12)
 [1] "1986-04-03" "1986-05-03" "1986-06-03" "1986-07-03" "1986-08-03"
 [6] "1986-09-03" "1986-10-03" "1986-11-03" "1986-12-03" "1987-01-03"
[11] "1987-02-03" "1987-03-03"
#numero de dias em um intervalo
intervalo1 / days(1)
[1] 11430
as.period(intervalo1, unit = "days")
[1] "11430d 0H 0M 0S"

Amostras e simulações

Para obter números aleatórioa seguindo uma distribuição uniforme, em que a probabilidade de se gerar qualquer ponto contido no espaço amostral é proporcional ao tamanho do intervalo

Histograma distribuição uniforme

set.seed(20)
margin.param <- list(
  l = 50,
  r = 25,
  b = 10,
  t = 10,
  pad = 4
)
aleatorios <- ~runif(2000, min = 0, max = 3)
fig <- plot_ly(x = aleatorios, type = "histogram")
fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param )
fig


Probabilidade em uma distribuição uniforme

Avaliar a probabilidade uniforme de um valor no intervalo
x <- seq(0, 100, by = 1)
y <- dunif(x, min = 10, max = 50) 
fig <- plot_ly(x =x, y=y, mode = 'lines+markers')
fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param )
fig

Probabilidade acumulada em uma distribuição uniforme

Avaliar a probabilidade acumulada uniforme de um valor dentro do intervalo
x <- seq(0, 100, by = 1)
y <- punif(x, min = 10, max = 50)
fig <- plot_ly(x =x, y=y, mode = 'lines+markers')
fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param )
fig

Para pegar uma amostra a partir de um domínio
amostra = c( "T", "R", "I", "A", "N", "G", "U", "L", "O", "S")
sample(amostra, replace = FALSE) #amostra sem repetição de valores
 [1] "L" "U" "R" "I" "S" "O" "T" "A" "G" "N"
sample(amostra, replace = TRUE) #amostra com repetição de valores
 [1] "R" "I" "R" "I" "U" "N" "O" "U" "G" "T"
sample(amostra, size = 20, replace = T, prob = c(1,2,1,1,4,3,1,1,1,1)) #5 amostras
 [1] "U" "S" "S" "G" "O" "N" "N" "G" "N" "O" "N" "L" "R" "G" "N" "G" "N" "N" "U"
[20] "R"
#as letras R,N e G estão com pesos maiores, com maior probabilidade de serem sorteados

Para fazer simulações, podemos usar as distribuições normal e binomial para amostras com valores mais “naturais”.

Números aleatórios seguindo uma distribuição normal

set.seed(902)
aleatorios <- data.frame(nums = rnorm(2000))

fig <- plot_ly(data = aleatorios, y=aleatorios$nums, type = 'scatter', mode = 'markers')
fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param )
fig
p <- ggplot(aleatorios, aes(nums)) + 
  geom_histogram(aes(y = ..density..), alpha = 0.7, fill = "#333333") +
  geom_density(fill = "#ff4d4d", alpha = 0.5) + 
  theme(panel.background = element_rect(fill = '#ffffff'))
  
  
  ggplotly(p) %>% 
  layout(autosize = F, width = 500, height = 300, margin = margin.param )
Alterando os valores de média e desvio padrão, temos distribuições normais de diferentes formatos
aleatorios2 <- data.frame(nums = rnorm(2000, mean = 1, sd = 1.5))
aleatorios2$name <- 'mean=1,sd=1.5'
aleatorios3 <- data.frame(nums = rnorm(2000, mean = 2, sd = 3), name = 'mean=2,sd=3')

aleatorios$name <- 'mean=0,sd=1'

aleatorios.df <- rbind(aleatorios, aleatorios2, aleatorios3)
p <- ggplot(aleatorios.df, aes(nums, fill=name)) + geom_density(alpha = 0.2)

ggplotly(p) %>% 
  layout(autosize = F, width = 500, height = 300, margin = margin.param )

Probabilidade em uma distribuição normal

Dada uma média e um desvio padrão, podemos avaliar a propabilidade da normal de um valor
x <- seq(- 5, 5, by = 0.05) 
y <- dnorm(x, mean = 0, sd=1) 
ggplotly(p) %>% 
  layout(autosize = F, width = 500, height = 300, margin = margin.param )

Probabilidade acumulada em uma distribuição normal

Para avaliar a probabilidade acumulada da normal de um valor
x <- seq(- 5, 5, by = 0.05)
y <- pnorm(x, mean = 0, sd = 1)
#plot_ly(x =x, y=y, mode = 'lines+markers')

Exemplo de simulação de um modelo linear

Considerando o seguinte modelo linear: \[y=\beta_0+\beta_1x+\varepsilon\] em que \[\beta_0=0.5\] \[\beta_1=2.0\] \[x\sim \mathcal{N}(0;1^2)\] \[\varepsilon\sim \mathcal{N}(0; 2^2)\]

set.seed(346)
x = rnorm(200, mean = 0, sd = 1)
e = rnorm(200, mean = 0, sd = 2)
y = 0.5 + 2 * x + e

fig <- plot_ly( x = x, y = y, type = "scatter" )
fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param )
fig

Loops e Funções

Row

IF e ELSE

x<-0

if(x > 0){
  sinal <- "positivo"
}else if(x == 0){
  sinal <- "neutro"
}else{
  sinal <- "negativo"
}

sinal
[1] "neutro"
ifelse(1>0, "verdade", "mentira")
[1] "verdade"

Loops

Loop para calcular o valor acumulado de passageiros ao longo do tempo.
Os valores são armazenados em um vetor
acumulado <- c(0)
for(i in AirPassengers){
  acumulado <- c(acumulado, tail(acumulado, 1)+i) #adiciona ao vetor a soma do último valor com a quantidade de passageiros do registro
}
acumulado <- acumulado[-1] #Remove o 0
acumulado
  [1]   112   230   362   491   612   747   895  1043  1179  1298  1402  1520
 [13]  1635  1761  1902  2037  2162  2311  2481  2651  2809  2942  3056  3196
 [25]  3341  3491  3669  3832  4004  4182  4381  4580  4764  4926  5072  5238
 [37]  5409  5589  5782  5963  6146  6364  6594  6836  7045  7236  7408  7602
 [49]  7798  7994  8230  8465  8694  8937  9201  9473  9710  9921 10101 10302
 [61] 10506 10694 10929 11156 11390 11654 11956 12249 12508 12737 12940 13169
 [73] 13411 13644 13911 14180 14450 14765 15129 15476 15788 16062 16299 16577
 [85] 16861 17138 17455 17768 18086 18460 18873 19278 19633 19939 20210 20516
 [97] 20831 21132 21488 21836 22191 22613 23078 23545 23949 24296 24601 24937
[109] 25277 25595 25957 26305 26668 27103 27594 28099 28503 28862 29172 29509
[121] 29869 30211 30617 31013 31433 31905 32453 33012 33475 33882 34244 34649
[133] 35066 35457 35876 36337 36809 37344 37966 38572 39080 39541 39931 40363

Funções

O R já possui muitas funções implementadas em suas bibliotecas como por exemplo a função mean(), que calcula a média.
mean(1:10)
[1] 5.5
#View(mean) #Podemos ver a implementação dessas funções
Podemos passar funções como parâmetros de outras funções
round(mean(1:10)) #Arredonda um valor numérico
[1] 6
Podemos desenvolver nossas próprias funções. Por exemplo, a função fatorial recursiva.
fatorial <- function(n){
  if(n==1 || n==0){
    return(1)
  }
  return(n * fatorial(n-1))
}

fatorial(5)
[1] 120
fatorial(10)
[1] 3628800


Obtendo dados no R

Row

Download

Podemos fazer download de datasets da internet.
A função abaixo, verifica se a pasta ‘data’ existe, se não existir, cria a pasta e em seguida faz o download do arquivo passado na url e armazena nela.
download.data <- function(file.url, file.local = NA){
  if(!file.exists('data')){
    dir.create('data')
  }
  if(is.na(file.local)){
    file.local = file.path('./data', basename(file.url))
  }
  download.file(url = file.url, destfile = file.local , mode='wb')
}
Utilizando a função para baixar um arquivo csv
download.data('https://storage.googleapis.com/ds-publico/Copas-Jogadores.csv')

Leitura de arquivos

Para ler arquivos csv
library(readr)
Copas_Jogadores <- read_csv("data/Copas-Jogadores.csv", 
                            col_types = cols(MatchID = col_integer(), 
                                             `Shirt Number` = col_integer()), 
                            na = "NA", skip = 5)
Copas_Jogadores
# A tibble: 37,779 x 9
   `201` `1096` FRA   `CAUDRON Raoul (~ S       `0` `Ernest LIBERAT~ X8    X9   
   <dbl>  <dbl> <chr> <chr>             <chr> <dbl> <chr>            <chr> <chr>
 1   201   1096 MEX   LUQUE Juan (MEX)  S         0 Rafael GARZA     "C"   ""   
 2   201   1096 FRA   CAUDRON Raoul (F~ S         0 Andre MASCHINOT  ""    "G43~
 3   201   1096 MEX   LUQUE Juan (MEX)  S         0 Hilario LOPEZ    ""    ""   
 4   201   1096 FRA   CAUDRON Raoul (F~ S         0 Etienne MATTLER  ""    ""   
 5   201   1096 MEX   LUQUE Juan (MEX)  S         0 Dionisio MEJIA   ""    ""   
 6   201   1096 FRA   CAUDRON Raoul (F~ S         0 Marcel PINEL     ""    ""   
 7   201   1096 MEX   LUQUE Juan (MEX)  S         0 Felipe ROSAS     ""    ""   
 8   201   1096 FRA   CAUDRON Raoul (F~ S         0 Alex VILLAPLANE  "C"   ""   
 9   201   1096 MEX   LUQUE Juan (MEX)  S         0 Manuel ROSAS     ""    ""   
10   201   1096 FRA   CAUDRON Raoul (F~ S         0 Lucien LAURENT   ""    "G19~
# ... with 37,769 more rows
class(Copas_Jogadores)
[1] "spec_tbl_df" "tbl_df"      "tbl"         "data.frame" 
Para ler arquivo excel
library(openxlsx)
download.data('https://storage.googleapis.com/ds-publico/cameras.baltimore.xlsx')
baltimore <- read.xlsx("data/cameras.baltimore.xlsx")

str(baltimore)
'data.frame':   80 obs. of  7 variables:
 $ address     : chr  "S CATON AVE & BENSON AVE" "S CATON AVE & BENSON AVE" "WILKENS AVE & PINE HEIGHTS AVE" "THE ALAMEDA & E 33RD ST" ...
 $ direction   : chr  "N/B" "S/B" "E/B" "S/B" ...
 $ street      : chr  "Caton Ave" "Caton Ave" "Wilkens Ave" "The Alameda" ...
 $ crossStreet : chr  "Benson Ave" "Benson Ave" "Pine Heights" "33rd St" ...
 $ intersection: chr  "Caton Ave & Benson Ave" "Caton Ave & Benson Ave" "Wilkens Ave & Pine Heights" "The Alameda  & 33rd St" ...
 $ Lat         : num  39.3 39.3 39.3 39.3 39.3 ...
 $ Long        : num  -76.7 -76.7 -76.7 -76.6 -76.6 ...


Manipulação de dados

Row

Mutate

O pacote dplyr possui funções que facilitam a manipulação de dados.
A função mutate adiciona uma coluna ao data frame

library(dplyr)

star.wars.modificado <- starwars %>% 
  mutate(imc = mass / ((height / 100) ^ 2))

star.wars.modificado %>% glimpse()
Rows: 87
Columns: 15
$ name       <chr> "Luke Skywalker", "C-3PO", "R2-D2", "Darth Vader", "Leia...
$ height     <int> 172, 167, 96, 202, 150, 178, 165, 97, 183, 182, 188, 180...
$ mass       <dbl> 77.0, 75.0, 32.0, 136.0, 49.0, 120.0, 75.0, 32.0, 84.0, ...
$ hair_color <chr> "blond", NA, NA, "none", "brown", "brown, grey", "brown"...
$ skin_color <chr> "fair", "gold", "white, blue", "white", "light", "light"...
$ eye_color  <chr> "blue", "yellow", "red", "yellow", "brown", "blue", "blu...
$ birth_year <dbl> 19.0, 112.0, 33.0, 41.9, 19.0, 52.0, 47.0, NA, 24.0, 57....
$ sex        <chr> "male", "none", "none", "male", "female", "male", "femal...
$ gender     <chr> "masculine", "masculine", "masculine", "masculine", "fem...
$ homeworld  <chr> "Tatooine", "Tatooine", "Naboo", "Tatooine", "Alderaan",...
$ species    <chr> "Human", "Droid", "Droid", "Human", "Human", "Human", "H...
$ films      <list> [<"The Empire Strikes Back", "Revenge of the Sith", "Re...
$ vehicles   <list> [<"Snowspeeder", "Imperial Speeder Bike">, <>, <>, <>, ...
$ starships  <list> [<"X-wing", "Imperial shuttle">, <>, <>, "TIE Advanced ...
$ imc        <dbl> 26.02758, 26.89232, 34.72222, 33.33007, 21.77778, 37.874...

Filter

Para filtrar os dados de um data frame
starwars %>% filter(species == "Droid") %>% print(n = 10, width = Inf)
# A tibble: 6 x 14
  name   height  mass hair_color skin_color  eye_color birth_year sex  
  <chr>   <int> <dbl> <chr>      <chr>       <chr>          <dbl> <chr>
1 C-3PO     167    75 <NA>       gold        yellow           112 none 
2 R2-D2      96    32 <NA>       white, blue red               33 none 
3 R5-D4      97    32 <NA>       white, red  red               NA none 
4 IG-88     200   140 none       metal       red               15 none 
5 R4-P17     96    NA none       silver, red red, blue         NA none 
6 BB8        NA    NA none       none        black             NA none 
  gender    homeworld species films     vehicles  starships
  <chr>     <chr>     <chr>   <list>    <list>    <list>   
1 masculine Tatooine  Droid   <chr [6]> <chr [0]> <chr [0]>
2 masculine Naboo     Droid   <chr [7]> <chr [0]> <chr [0]>
3 masculine Tatooine  Droid   <chr [1]> <chr [0]> <chr [0]>
4 masculine <NA>      Droid   <chr [1]> <chr [0]> <chr [0]>
5 feminine  <NA>      Droid   <chr [2]> <chr [0]> <chr [0]>
6 masculine <NA>      Droid   <chr [1]> <chr [0]> <chr [0]>
star.wars.modificado %>% filter(imc > 25) %>% glimpse()
Rows: 25
Columns: 15
$ name       <chr> "Luke Skywalker", "C-3PO", "R2-D2", "Darth Vader", "Owen...
$ height     <int> 172, 167, 96, 202, 178, 165, 97, 183, 175, 170, 180, 66,...
$ mass       <dbl> 77, 75, 32, 136, 120, 75, 32, 84, 1358, 77, 110, 17, 75,...
$ hair_color <chr> "blond", NA, NA, "none", "brown, grey", "brown", NA, "bl...
$ skin_color <chr> "fair", "gold", "white, blue", "white", "light", "light"...
$ eye_color  <chr> "blue", "yellow", "red", "yellow", "blue", "blue", "red"...
$ birth_year <dbl> 19.0, 112.0, 33.0, 41.9, 52.0, 47.0, NA, 24.0, 600.0, 21...
$ sex        <chr> "male", "none", "none", "male", "male", "female", "none"...
$ gender     <chr> "masculine", "masculine", "masculine", "masculine", "mas...
$ homeworld  <chr> "Tatooine", "Tatooine", "Naboo", "Tatooine", "Tatooine",...
$ species    <chr> "Human", "Droid", "Droid", "Human", "Human", "Human", "D...
$ films      <list> [<"The Empire Strikes Back", "Revenge of the Sith", "Re...
$ vehicles   <list> [<"Snowspeeder", "Imperial Speeder Bike">, <>, <>, <>, ...
$ starships  <list> [<"X-wing", "Imperial shuttle">, <>, <>, "TIE Advanced ...
$ imc        <dbl> 26.02758, 26.89232, 34.72222, 33.33007, 37.87401, 27.548...


Select

Para ordenar e filtrar colunas
starwars %>% select(name, ends_with("color"))
# A tibble: 87 x 4
   name               hair_color    skin_color  eye_color
   <chr>              <chr>         <chr>       <chr>    
 1 Luke Skywalker     blond         fair        blue     
 2 C-3PO              <NA>          gold        yellow   
 3 R2-D2              <NA>          white, blue red      
 4 Darth Vader        none          white       yellow   
 5 Leia Organa        brown         light       brown    
 6 Owen Lars          brown, grey   light       blue     
 7 Beru Whitesun lars brown         light       blue     
 8 R5-D4              <NA>          white, red  red      
 9 Biggs Darklighter  black         light       brown    
10 Obi-Wan Kenobi     auburn, white fair        blue-gray
# ... with 77 more rows
star.wars.modificado %>% filter(imc > 25) %>% select(name:species, -ends_with("color"), imc)
# A tibble: 25 x 9
   name         height  mass birth_year sex      gender  homeworld species   imc
   <chr>         <int> <dbl>      <dbl> <chr>    <chr>   <chr>     <chr>   <dbl>
 1 Luke Skywal~    172    77       19   male     mascul~ Tatooine  Human    26.0
 2 C-3PO           167    75      112   none     mascul~ Tatooine  Droid    26.9
 3 R2-D2            96    32       33   none     mascul~ Naboo     Droid    34.7
 4 Darth Vader     202   136       41.9 male     mascul~ Tatooine  Human    33.3
 5 Owen Lars       178   120       52   male     mascul~ Tatooine  Human    37.9
 6 Beru Whites~    165    75       47   female   femini~ Tatooine  Human    27.5
 7 R5-D4            97    32       NA   none     mascul~ Tatooine  Droid    34.0
 8 Biggs Darkl~    183    84       24   male     mascul~ Tatooine  Human    25.1
 9 Jabba Desil~    175  1358      600   hermaph~ mascul~ Nal Hutta Hutt    443. 
10 Wedge Antil~    170    77       21   male     mascul~ Corellia  Human    26.6
# ... with 15 more rows

Nesse último filtro utilizamos ‘:’ para indicar uma sequência de colunas conhecidas e o ‘-’ para sinalizar que queríamos excluir as colunas com nomes terminados com ‘color’.

Arrange

Utilizado para reodenar as linhas de um data frame
starwars %>% arrange(desc(mass)) %>% select(name, ends_with("color"), mass)
# A tibble: 87 x 5
   name                  hair_color  skin_color       eye_color      mass
   <chr>                 <chr>       <chr>            <chr>         <dbl>
 1 Jabba Desilijic Tiure <NA>        green-tan, brown orange         1358
 2 Grievous              none        brown, white     green, yellow   159
 3 IG-88                 none        metal            red             140
 4 Darth Vader           none        white            yellow          136
 5 Tarfful               brown       brown            blue            136
 6 Owen Lars             brown, grey light            blue            120
 7 Bossk                 none        green            red             113
 8 Chewbacca             brown       unknown          blue            112
 9 Jek Tono Porkins      brown       fair             blue            110
10 Dexter Jettster       none        brown            yellow          102
# ... with 77 more rows
star.wars.modificado %>% arrange(imc) %>% select(name, imc)
# A tibble: 87 x 2
   name            imc
   <chr>         <dbl>
 1 Wat Tambor     12.9
 2 Adi Gallia     14.8
 3 Sly Moore      15.1
 4 Roos Tarpals   16.3
 5 Padmé Amidala  16.5
 6 Lama Su        16.8
 7 Jar Jar Binks  17.2
 8 Ayla Secura    17.4
 9 Shaak Ti       18.0
10 Barriss Offee  18.1
# ... with 77 more rows


Agregações

#Agrupando, sumarizando e filtrando
starwars %>% group_by(species) %>% summarise( count = n(), mass = mean(mass, na.rm = TRUE) ) %>% filter(count > 1) %>% arrange(count)
# A tibble: 9 x 3
  species  count  mass
  <chr>    <int> <dbl>
1 Kaminoan     2  88  
2 Mirialan     2  53.1
3 Twi'lek      2  55  
4 Wookiee      2 124  
5 Zabrak       2  80  
6 Gungan       3  74  
7 <NA>         4  48  
8 Droid        6  69.8
9 Human       35  82.8

Primeiro, agrupamos por espécies, depois sumarizamos pelas colunas count, que utiliza a função ’n()’para apresentar o tamanho do grupo, e a coluna mass que apresenta a média da massa desse grupo, removendo os valores não disponíveis. O próximo passo foi filtrar para mostrar apenas os grupos com mais de 1 elemento, e por fim, ordenar as linhas de forma crescente, de acordo com a quantidade de elementos nos grupos.

---
title: "Estudo R"
output:
  flexdashboard::flex_dashboard:
    social: menu
    source_code: embed
    vertical_layout: fill
    orientation: rows
---
```{r include=FALSE}
knitr::opts_chunk$set(echo = TRUE, error=TRUE)
#para limpar as variáveis do ambiente
rm(list = ls())
library(flexdashboard)
library(lubridate)
library(plotly)
```

Estruturas de dados
=======================================================================


Row {data-height=650 data-width=300 .tabset}
-------------------------------------
### Vetor

Declaração de vetores.

```{r}
vet_int <- c(5L, 23L, 58L, 47L)
vet_bool <- c(F, T, T, T)
vet_num <- c(109.1, 165.3, 147.7, 182.5)
vet_char<- c("Tim", "Bill", "Rosa", "Alex")
```

Também é possível declacar um vetor de números imaginários
```{r}
vet_img <- c(1.50i, 2.50i, 3.50i, 4.50i)
```

Verificando as classes dos vetores.
Nos vetores, todos os elementos são do mesmo tipo de dado. ```{r} class(vet_int) class(vet_bool) class(vet_num) class(vet_char) class(vet_img) ``` Podemos verificar se os elementos do vetor vet_int são realmente inteiros. ```{r} is.integer(vet_int) ``` Operações com vetores ```{r} vet_int * 2 #multiplica cada elemento por 2 vet_num / 3.4 vet_int + 7 ``` ```{r} vet_int + c(3, 4, 1) ``` Como os dois vetores não possuiam o mesmo tamanho, o vetor menor foi repetido até completar o vetor maior. Isso é chamado *Reciclagem*.
Vetores aceitam apenas um tipo de dado, na seguinte ordem de precedência: character > complex > numeric > integer > logical ```{r} x <- c(5L, 6.4) class(x) # o vetor ficou como numérico x <- c(5L, 6.4, "abc") class(x) # o vetor passou a ser character ``` Podemos forçar um vetor a ser de um tipo específico ```{r} x <- -3:2 x class(x) y <-as.numeric(x) y class(y) y <- as.logical(x) y # apenos 0 é false class(y) y <- as.character(x) y class(y) ``` ### Matriz Declaração de uma matriz 4*3 ```{r} matriz <- matrix(c(1:12), nrow = 4, ncol = 3, byrow = T) matriz ``` Verificando a classe e as dimensões da matriz: ```{r} paste("A classe é: ", class(matriz)[1] ) dimensoes <- dim(matriz) paste("As dimensões da matriz são: ", dimensoes[1], "x", dimensoes[2]) ``` Podemos criar uma matriz utilizando alguns dos vetores criados até agora. ```{r} matriz2 <- matrix(c(vet_char, vet_int, vet_num), nrow = 4, byrow = F) matriz2 ``` Como matrizes aceitam apenas um tipo de dado, acabamos transformando todos os elementos no tipo *character*.
Podemos utilizar a primeira coluna como nome das linhas, dessa forma, as demais variáveis vão assumir o tipo *numeric*, que é mais abrangente do que o tipo *integer* ```{r} matriz2 <- matrix(c(vet_int, vet_num), nrow = 4, byrow = F) rownames(matriz2) <- vet_char matriz2 ``` Agora, daremos nomes às colunas. ```{r} colnames(matriz2) <- c("idade", "altura(cm)") matriz2 ``` Subsets ```{r} matriz2[1,] #seleciona a primeira linha matriz2[,2] #seleciona a segunda coluna matriz2[2,2] #seleciona o elemento da segunda linha e segunda coluna ``` Matriz transposta ```{r} t(matriz2) ``` Multiplicação de matrizes ```{r} m1 <- matrix(1:8, nrow = 4, ncol = 2) m2 <- matrix(10:17, nrow = 2, ncol = 4) m1 %*% m2 ``` Matriz inversa e diagonal principal ```{r} m1 <- matrix(1:4, nrow = 2, ncol = 2) m1 solve(m1) # matriz inversa, a matriz tem que ser quadrada diag(m1) #diagonal principal ``` ### Dataframe Dataframes são similares à matrizes, mas possuem funções específicas como busca e indexação. Permitem que cada coluna seja de um tipo diferente. ```{r} df <- data.frame(vet_int, vet_num, row.names = vet_char) colnames(df) <- c("idade", "altura(cm)") df ``` Verificando os tipos das colunas: ```{r} str(df) ``` Podemos adicionar mais uma coluna: ```{r} df <- cbind(df, maioridade = df$idade > 18) df ``` E uma nova linha ```{r} df <- rbind(df, "Pam" = list(32L, 172, TRUE)) df ``` As 2 primeiras linhas desse dataset: ```{r} head(df, n=2) ``` As duas últimas linhas: ```{r} tail(df, n=2) ``` ### Lista Listas permitem que cada elemento seja de um tipo de dado.
Um conjunto de listas do mesmo tamanho forma um dataset. ```{r} lista1 <- list("lista", 99L, 0.983, F) lista1 ``` ```{r} str(lista1) ``` Podemos criar uma lista com todos os vetores criados até agora ```{r} lista2 <- list("boolean"=vet_bool, "char"=vet_char, vet_img, vet_int, vet_num) lista2 ``` ```{r} str(lista2) ``` Subsets: ```{r} lista2[1] #retorna uma sub-lista lista2[[1]] #retorna o primeiro elemento da lista lista2$boolean #filtra pelo nome do elemento ``` ### Fator Fatores servem para expressar variáveis categóricas. ```{r} temperatura <- c("frio", "calor", "ameno", "calor", "ameno", "frio") temperatura.factor <- factor(temperatura, ordered = T, levels=c("frio", "ameno", "calor")) temperatura.factor ``` ```{r} unclass(temperatura.factor) ``` ```{r} levels(temperatura.factor) ``` Datas ======================================================================= Data e hora ```{r} dia_texto <- "01/08/2020 T 16:35:23" dia_date <- as.Date(dia_texto,format="%d/%m/%Y T %H:%M:%S",tz="America/Sao_Paulo") dia_date unclass(dia_date) #valor representa (01/08/2020) - (01/01/1970) em dias ``` POSIXct - número de segundos a partir de 01/01/1970 ```{r} dia.time1 <- as.POSIXct(dia_texto,format="%d/%m/%Y T %H:%M:%S",tz="America/Sao_Paulo") dia.time1 unclass(dia.time1) #valor representa (01/08/2020) - (01/01/1970) em segundos ``` POSIXlt - Lista com elementos ano, mês, dia, hora, entre outros ```{r} dia.time2 <- as.POSIXlt(dia_texto,format="%d/%m/%Y T %H:%M:%S",tz="America/Sao_Paulo") dia.time2 ``` ```{r} unclass(dia.time2) ``` Como dia.time tem o elemeno chamado year, podemos fazer: ```{r} dia.time2$year ``` O pacote lubridate facilita a manipulação de datas ```{r} library(lubridate) ymd("20200801") #Cria uma data sabendo que está na ordem ano, mês, dia dmy("01.08.2020") #Cria uma data sabendo que está na ordem dia, mês, ano ``` ```{r} nascimento <- ymd_hms(19990704130752) nascimento year(nascimento) #ano da data second(nascimento) #segundos da data wday(nascimento) #dia da semana wday(nascimento, label = T) month(nascimento, label = T) ``` Essas funções também podem ser usadas para atribuir componentes a datas: ```{r} dia1 <- ymd(20180417, tz = "America/Sao_Paulo") hour(dia1) <- 13 second(dia1) <- 24 dia1 ``` Fuso horário ```{r} tz(dia1) with_tz(dia1, tzone = "US/Alaska") #data/hora equivalente em outro timezone dia1 <- force_tz(dia1, tz = "Asia/Singapore") #altera o timezone tz(dia1) ``` Operações com datas ```{r} data_inicio <- dmy("03/03/1986") data_fim <- dmy("18/06/2017") intervalo1 <- interval(data_inicio, data_fim) intervalo1 class(intervalo1) ``` Outras formas de obter o intervalo ```{r} data_fim - data_inicio difftime(data_fim, data_inicio) difftime(data_fim, data_inicio, unit="secs") difftime(data_fim, data_inicio, unit="days") ``` É possível verificar se dois intervalos de tempo se sobrepõem ```{r} intervalo2 <- dmy("04-03-2000") %--% dmy("20/03/2018") # Operador %--% para intervalo int_overlaps(intervalo1, intervalo2) ``` Aritmética com datas ```{r} days(1) #cria um dia ddays(1) # cria uma duração de um dia em segundos data_inicio + ddays(1) data_inicio + years(2) #Criar datas recorrentes data_inicio + months(1:12) #numero de dias em um intervalo intervalo1 / days(1) as.period(intervalo1, unit = "days") ``` Amostras e simulações ======================================================================= Para obter números aleatórioa seguindo uma distribuição uniforme, em que a probabilidade de se gerar qualquer ponto contido no espaço amostral é proporcional ao tamanho do intervalo #### Histograma distribuição uniforme ```{r} set.seed(20) margin.param <- list( l = 50, r = 25, b = 10, t = 10, pad = 4 ) aleatorios <- ~runif(2000, min = 0, max = 3) fig <- plot_ly(x = aleatorios, type = "histogram") fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param ) fig ```
#### Probabilidade em uma distribuição uniforme Avaliar a probabilidade uniforme de um valor no intervalo ```{r} x <- seq(0, 100, by = 1) y <- dunif(x, min = 10, max = 50) fig <- plot_ly(x =x, y=y, mode = 'lines+markers') fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param ) fig ``` #### Probabilidade acumulada em uma distribuição uniforme Avaliar a probabilidade acumulada uniforme de um valor dentro do intervalo ```{r} x <- seq(0, 100, by = 1) y <- punif(x, min = 10, max = 50) fig <- plot_ly(x =x, y=y, mode = 'lines+markers') fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param ) fig ```
Para pegar uma amostra a partir de um domínio ```{r} amostra = c( "T", "R", "I", "A", "N", "G", "U", "L", "O", "S") sample(amostra, replace = FALSE) #amostra sem repetição de valores sample(amostra, replace = TRUE) #amostra com repetição de valores sample(amostra, size = 20, replace = T, prob = c(1,2,1,1,4,3,1,1,1,1)) #5 amostras #as letras R,N e G estão com pesos maiores, com maior probabilidade de serem sorteados ```
Para fazer simulações, podemos usar as distribuições normal e binomial para amostras com valores mais "naturais". #### Números aleatórios seguindo uma distribuição normal ```{r} set.seed(902) aleatorios <- data.frame(nums = rnorm(2000)) fig <- plot_ly(data = aleatorios, y=aleatorios$nums, type = 'scatter', mode = 'markers') fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param ) fig ``` ```{r} p <- ggplot(aleatorios, aes(nums)) + geom_histogram(aes(y = ..density..), alpha = 0.7, fill = "#333333") + geom_density(fill = "#ff4d4d", alpha = 0.5) + theme(panel.background = element_rect(fill = '#ffffff')) ggplotly(p) %>% layout(autosize = F, width = 500, height = 300, margin = margin.param ) ``` Alterando os valores de média e desvio padrão, temos distribuições normais de diferentes formatos ```{r} aleatorios2 <- data.frame(nums = rnorm(2000, mean = 1, sd = 1.5)) aleatorios2$name <- 'mean=1,sd=1.5' aleatorios3 <- data.frame(nums = rnorm(2000, mean = 2, sd = 3), name = 'mean=2,sd=3') aleatorios$name <- 'mean=0,sd=1' aleatorios.df <- rbind(aleatorios, aleatorios2, aleatorios3) p <- ggplot(aleatorios.df, aes(nums, fill=name)) + geom_density(alpha = 0.2) ggplotly(p) %>% layout(autosize = F, width = 500, height = 300, margin = margin.param ) ``` #### Probabilidade em uma distribuição normal Dada uma média e um desvio padrão, podemos avaliar a propabilidade da normal de um valor ```{r} x <- seq(- 5, 5, by = 0.05) y <- dnorm(x, mean = 0, sd=1) ggplotly(p) %>% layout(autosize = F, width = 500, height = 300, margin = margin.param ) ``` #### Probabilidade acumulada em uma distribuição normal Para avaliar a probabilidade acumulada da normal de um valor ```{r} x <- seq(- 5, 5, by = 0.05) y <- pnorm(x, mean = 0, sd = 1) #plot_ly(x =x, y=y, mode = 'lines+markers') ``` #### Exemplo de simulação de um modelo linear Considerando o seguinte modelo linear: $$y=\beta_0+\beta_1x+\varepsilon$$ em que $$\beta_0=0.5$$ $$\beta_1=2.0$$ $$x\sim \mathcal{N}(0;1^2)$$ $$\varepsilon\sim \mathcal{N}(0; 2^2)$$ ```{r} set.seed(346) x = rnorm(200, mean = 0, sd = 1) e = rnorm(200, mean = 0, sd = 2) y = 0.5 + 2 * x + e fig <- plot_ly( x = x, y = y, type = "scatter" ) fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param ) fig ``` Loops e Funções ======================================================================= Row {data-height=650 data-width=300 .tabset} ------------------------------------- ### IF e ELSE ```{r} x<-0 if(x > 0){ sinal <- "positivo" }else if(x == 0){ sinal <- "neutro" }else{ sinal <- "negativo" } sinal ``` ```{r} ifelse(1>0, "verdade", "mentira") ``` ### Loops Loop para calcular o valor acumulado de passageiros ao longo do tempo.
Os valores são armazenados em um vetor ```{r} acumulado <- c(0) for(i in AirPassengers){ acumulado <- c(acumulado, tail(acumulado, 1)+i) #adiciona ao vetor a soma do último valor com a quantidade de passageiros do registro } acumulado <- acumulado[-1] #Remove o 0 acumulado ``` ### Funções O R já possui muitas funções implementadas em suas bibliotecas como por exemplo a função mean(), que calcula a média. ```{r} mean(1:10) #View(mean) #Podemos ver a implementação dessas funções ``` Podemos passar funções como parâmetros de outras funções ```{r} round(mean(1:10)) #Arredonda um valor numérico ``` Podemos desenvolver nossas próprias funções. Por exemplo, a função fatorial recursiva. ```{r} fatorial <- function(n){ if(n==1 || n==0){ return(1) } return(n * fatorial(n-1)) } fatorial(5) fatorial(10) ```
Obtendo dados no R ======================================================================= Row {data-height=650 data-width=300 .tabset} ------------------------------------- ### Download Podemos fazer download de datasets da internet.
A função abaixo, verifica se a pasta 'data' existe, se não existir, cria a pasta e em seguida faz o download do arquivo passado na url e armazena nela. ```{r} download.data <- function(file.url, file.local = NA){ if(!file.exists('data')){ dir.create('data') } if(is.na(file.local)){ file.local = file.path('./data', basename(file.url)) } download.file(url = file.url, destfile = file.local , mode='wb') } ``` Utilizando a função para baixar um arquivo csv ```{r} download.data('https://storage.googleapis.com/ds-publico/Copas-Jogadores.csv') ``` ### Leitura de arquivos Para ler arquivos csv ```{r} library(readr) Copas_Jogadores <- read_csv("data/Copas-Jogadores.csv", col_types = cols(MatchID = col_integer(), `Shirt Number` = col_integer()), na = "NA", skip = 5) Copas_Jogadores class(Copas_Jogadores) ``` Para ler arquivo excel ```{r} library(openxlsx) download.data('https://storage.googleapis.com/ds-publico/cameras.baltimore.xlsx') baltimore <- read.xlsx("data/cameras.baltimore.xlsx") str(baltimore) ```
Manipulação de dados ======================================================================= Row {data-height=650 data-width=300 .tabset} ------------------------------------- ### Mutate O pacote **dplyr** possui funções que facilitam a manipulação de dados.
A função mutate adiciona uma coluna ao data frame ```{r} library(dplyr) star.wars.modificado <- starwars %>% mutate(imc = mass / ((height / 100) ^ 2)) star.wars.modificado %>% glimpse() ``` ### Filter Para filtrar os dados de um data frame ```{r} starwars %>% filter(species == "Droid") %>% print(n = 10, width = Inf) star.wars.modificado %>% filter(imc > 25) %>% glimpse() ```
### Select Para ordenar e filtrar colunas ```{r} starwars %>% select(name, ends_with("color")) star.wars.modificado %>% filter(imc > 25) %>% select(name:species, -ends_with("color"), imc) ``` Nesse último filtro utilizamos ':' para indicar uma sequência de colunas conhecidas e o '-' para sinalizar que queríamos excluir as colunas com nomes terminados com 'color'.
### Arrange Utilizado para reodenar as linhas de um data frame ```{r} starwars %>% arrange(desc(mass)) %>% select(name, ends_with("color"), mass) star.wars.modificado %>% arrange(imc) %>% select(name, imc) ```
### Agregações ```{r} #Agrupando, sumarizando e filtrando starwars %>% group_by(species) %>% summarise( count = n(), mass = mean(mass, na.rm = TRUE) ) %>% filter(count > 1) %>% arrange(count) ``` Primeiro, agrupamos por espécies, depois sumarizamos pelas colunas count, que utiliza a função 'n()'para apresentar o tamanho do grupo, e a coluna mass que apresenta a média da massa desse grupo, removendo os valores não disponíveis. O próximo passo foi filtrar para mostrar apenas os grupos com mais de 1 elemento, e por fim, ordenar as linhas de forma crescente, de acordo com a quantidade de elementos nos grupos.